package ca.uwindsor.cs.deepweb.estimation.method.capturehistory;

import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

import ca.uwindsor.cs.deepweb.estimation.DataCollectorWithLimitationTop;
import ca.uwindsor.cs.deepweb.estimation.FilesContentIndexer;
import ca.uwindsor.cs.deepweb.estimation.RandomWordSelector;

public class RandomQueryReturnTopUsingCharactersUsingCharacter {
	protected short times;
	protected HashSet<String> unique;
	protected int total;
	protected int marked;
	protected int corpussize;
	protected int maxstepsize;
	protected Random r;
	protected StringBuilder result;
	protected String corpusindex;
	protected String dict;
	protected int topsize;

	private BigInteger nominator;
	private BigInteger denominator;
	private int CHesimtaed;
	/**
	 * @param corpusindex 
	 * @param dict 
	 * @param times
	 * 
	 */
	public RandomQueryReturnTopUsingCharactersUsingCharacter(String corpusindex, String dict, short times, int topsize) {
		this.corpusindex = corpusindex;
		this.dict = dict;
		this.times = times;
		this.topsize = topsize;
		result = new StringBuilder();
		// r = new Random();
		unique = new HashSet<String>();
		nominator = new BigInteger("0");
		denominator = new BigInteger("0");
	}

	public void query() throws Exception {
		IndexSearcher searcher = new IndexSearcher(corpusindex);
		Query query = null;
		Hits hits = null;
		QueryParser queryparser = new QueryParser(
				FilesContentIndexer.FIELD_CONTENT, new StandardAnalyzer());

		RandomWordSelector selector = new RandomWordSelector(dict, "UTF-8");

		Set<String> newid;
		HashSet<String> duplicated = new HashSet<String>();
//		double nominator = 0;
//		double denominator = 0;
		int orresult;
		double OR;
		float exponentofOR = -2.1f;
		
		DataCollectorWithLimitationTop datacollector = new DataCollectorWithLimitationTop(
				FilesContentIndexer.FIELD_ID, topsize);
		for (int i = 0; i < times; i++) {
			String c = selector.getRandomCharacter();
			query = queryparser.parse(c);
			hits = searcher.search(query);
			if(hits.length()==0){
				i--;
				continue;
			}

			newid = datacollector.add(hits);
			total += newid.size();

			duplicated.clear();
			duplicated.addAll(newid);
			duplicated.retainAll(unique);
			marked = duplicated.size();

			unique.addAll(newid);
//			System.out.println(unique.size());
//			if (unique.size()==0){
//				i--;
//				continue;
//			}
			//
			nominator = nominator.add(new BigInteger(Integer.toString(newid
					.size())).multiply(new BigInteger(Integer.toString(unique
					.size())).pow(2)));
			denominator = denominator.add(new BigInteger(Integer
					.toString(marked)).multiply(new BigInteger(Integer
					.toString(unique.size()))));
			if (denominator.intValue() != 0) {
				CHesimtaed = nominator.divide(denominator).intValue();
			} else {
				CHesimtaed = 0;
			}
			//

			//
			OR = total / (double) unique.size();
			orresult = (int) (unique.size() / (1 - Math.pow(OR, exponentofOR)));
			//
			result.append(c + "\t" + newid.size() + "\t" + duplicated.size()
					+ "\t" + unique.size() + "\t" +OR + "\t" + CHesimtaed + "\t"
					+ orresult + "\n");
		}
	}

	public String toString() {
		return result.toString();
	}

	public static void main(String[] args) {
		RandomQueryReturnTopUsingCharactersUsingCharacter rs = new RandomQueryReturnTopUsingCharactersUsingCharacter(
				"F:\\indexes\\zhwiki_20090116",
				"D:\\Research\\estimation\\Dictionary\\现代汉语词典.txt", (short)100,1000);
		try {
			rs.query();
			FileOutputStream fp;
			fp = new FileOutputStream(
					"D:\\Research\\estimation\\Result\\zhwiki\\OR\\zhwiki_100char_CH-OR.txt");
			fp.write(rs.toString().getBytes("UTF-8"));
			fp.flush();
			fp.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println(rs.toString());
	}
}
